package com.cycplus.test.ui

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.OverScroller
import androidx.core.view.ViewCompat
import kotlin.math.ceil

class MultiImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val imageSize = 48f // each image is 40x40 pixels
    private val images = mutableListOf<Bitmap>()
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val scroller = OverScroller(context)

    private var lastTouchX = 0f
    private var scrollOffsetX = 0f

    fun setImages(bitmaps: List<Bitmap>) {
        images.clear()
        images.addAll(bitmaps)
        requestLayout()
        invalidate()
    }

    fun printLog(msg: String) {
        Log.d("zyq", msg)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val desiredWidth = (images.size * imageSize).toInt()
        val desiredHeight = imageSize.toInt()

        val width = resolveSize(desiredWidth, widthMeasureSpec)
        val height = resolveSize(desiredHeight, heightMeasureSpec)
        printLog("onMeasure: $width, $height, $desiredWidth, $desiredHeight")
        setMeasuredDimension(width, height)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        printLog("onSizeChanged: $w, $h, $oldw, $oldh")
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val startIndex = maxOf(0, (scrollOffsetX / imageSize).toInt())
        val visibleCount = ceil(width / imageSize.toDouble()).toInt() + 1
        val endIndex = minOf(images.size - 1, startIndex + visibleCount)

        for (i in startIndex..endIndex) {
            val left = i * imageSize - scrollOffsetX
            val rect = RectF(left, 0f, left + imageSize, imageSize)
            canvas.drawBitmap(images[i], null, rect, paint)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                if (!scroller.isFinished) scroller.abortAnimation()
                lastTouchX = event.x
                return true
            }
            MotionEvent.ACTION_MOVE -> {
                val dx = lastTouchX - event.x
                lastTouchX = event.x
                scrollBy(dx)
                return true
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (!scroller.isFinished) invalidate()
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    private fun scrollBy(dx: Float) {
        scrollOffsetX = (scrollOffsetX + dx).coerceIn(0f, maxScrollOffset())
        invalidate()
    }

    private fun maxScrollOffset(): Float {
        return maxOf(0f, images.size * imageSize - width)
    }

    override fun computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollOffsetX = scroller.currX.toFloat()
            invalidate()
        }
    }

    fun fling(velocityX: Int) {
        scroller.fling(
            scrollOffsetX.toInt(), 0,
            -velocityX, 0,
            0, maxScrollOffset().toInt(),
            0, 0
        )
        ViewCompat.postInvalidateOnAnimation(this)
    }
}
